﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;

namespace YArchitech.Temp
{
	public static class DbUtils
	{
		public static bool IsRound(Connector conn)
		{
			return conn.Shape == 0;
		}

		public static bool IsLink(Connector con1, Connector con2)
		{
			return con1 != null && con2 != null && (con1.IsConnectedTo(con2) || con1.Origin.DistanceTo(con2.Origin) < DbUtils.Tol);
		}

		public static ConnectorManager GetElementConnectorManager(Element element)
		{
			ConnectorManager connectorManager;
			if (element is FamilyInstance)
			{
				connectorManager = (element as FamilyInstance).MEPModel.ConnectorManager;
			}
			else
			{
				connectorManager = (element as MEPCurve).ConnectorManager;
			}
			return connectorManager;
		}

		public static ConnectorSet GetElementConnectors(Element element)
		{
			ConnectorManager elementConnectorManager = DbUtils.GetElementConnectorManager(element);
			if (elementConnectorManager == null)
			{
				return null;
			}
			return elementConnectorManager.Connectors;
		}

		public static Connector GetConnectedConnector(Connector connector)
		{
			if (connector == null)
			{
				return null;
			}
			Connector result = null;
			foreach (object obj in connector.AllRefs)
			{
				Connector connector2 = (Connector)obj;
                if (connector2.ConnectorType == (ConnectorType)1 && !connector2.Owner.Id.IntegerValue.Equals(connector.Owner.Id.IntegerValue))
				{
					result = connector2;
					break;
				}
			}
			return result;
		}

		public static Connector GetOpenConnector(Element element, Connector inputConnector)
		{
			Connector connector = null;
			foreach (object obj in DbUtils.GetElementConnectors(element))
			{
				Connector connector2 = (Connector)obj;
				if (inputConnector == null || !connector2.IsConnectedTo(inputConnector))
				{
					if (!connector2.IsConnected)
					{
						connector = connector2;
						break;
					}
					foreach (object obj2 in connector2.AllRefs)
					{
						Connector connector3 = (Connector)obj2;
                        if (connector3.ConnectorType == (ConnectorType)1 && !connector3.Owner.Id.IntegerValue.Equals(connector2.Owner.Id.IntegerValue) && (inputConnector == null || !connector3.Owner.Id.IntegerValue.Equals(inputConnector.Owner.Id.IntegerValue)))
						{
							connector = DbUtils.GetOpenConnector(connector3.Owner, connector2);
							if (connector != null)
							{
								break;
							}
						}
					}
				}
			}
			return connector;
		}

		public static MEPSystem ExtractMechanicalOrPipingSystem(Element selectedElement)
		{
			MEPSystem result = null;
			if (selectedElement is MEPSystem)
			{
				if (selectedElement is MechanicalSystem || selectedElement is PipingSystem)
				{
					return selectedElement as MEPSystem;
				}
			}
			else
			{
				FamilyInstance familyInstance = selectedElement as FamilyInstance;
				if (familyInstance != null)
				{
					MEPModel mepmodel = familyInstance.MEPModel;
					ConnectorSet connectors = null;
					try
					{
						connectors = mepmodel.ConnectorManager.Connectors;
					}
					catch (Exception)
					{
					}
					result = DbUtils.ExtractSystemFromConnectors(connectors);
				}
				else
				{
					MEPCurve mepcurve = selectedElement as MEPCurve;
					if (mepcurve != null)
					{
						result = DbUtils.ExtractSystemFromConnectors(mepcurve.ConnectorManager.Connectors);
					}
				}
			}
			return result;
		}

		public static MEPSystem ExtractSystemFromConnectors(ConnectorSet connectors)
		{
			MEPSystem result = null;
			if (connectors == null || connectors.Size == 0)
			{
				return null;
			}
			List<MEPSystem> list = new List<MEPSystem>();
			foreach (object obj in connectors)
			{
				MEPSystem mepsystem = ((Connector)obj).MEPSystem;
				if (mepsystem != null)
				{
					MechanicalSystem mechanicalSystem = mepsystem as MechanicalSystem;
					if (mechanicalSystem != null)
					{
						if (mechanicalSystem.IsWellConnected)
						{
							list.Add(mepsystem);
						}
					}
					else
					{
						PipingSystem pipingSystem = mepsystem as PipingSystem;
						if (pipingSystem != null && pipingSystem.IsWellConnected)
						{
							list.Add(mepsystem);
						}
					}
				}
			}
			if (list.Count != 0)
			{
				int num = 0;
				foreach (MEPSystem mepsystem2 in list)
				{
					if (mepsystem2.Elements.Size > num)
					{
						result = mepsystem2;
						num = mepsystem2.Elements.Size;
					}
				}
			}
			return result;
		}

		public static void MatchConnector(Connector connModify, Connector connRef)
		{
			if (DbUtils.IsRound(connModify))
			{
				connModify.Radius = connRef.Radius;
				return;
			}
			XYZ basisX = connRef.CoordinateSystem.BasisX;
			if (GeUtils.IsParallel(connModify.CoordinateSystem.BasisX, basisX))
			{
				connModify.Width = connRef.Width;
				connModify.Height = connRef.Height;
				return;
			}
			connModify.Height = connRef.Width;
			connModify.Width = connRef.Height;
		}

		public static void SetConnectorSize(Connector connector, double WidthOrDia, double Height)
		{
			if (DbUtils.IsRound(connector))
			{
				connector.Radius = WidthOrDia / 2.0;
				return;
			}
			if (connector.Width < connector.Height)
			{
				connector.Width = Height;
				connector.Height = WidthOrDia;
				return;
			}
			connector.Width = WidthOrDia;
			connector.Height = Height;
		}

		public static bool TestCategory(Element elem, BuiltInCategory buildInCat)
		{
			if (elem == null)
			{
				return false;
			}
			Category category = elem.Document.Settings.Categories.get_Item(buildInCat);
			return elem.Category.Id == category.Id;
		}

		public static bool IsDuct(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_DuctCurves);
		}

		public static bool IsFlexDuct(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_FlexDuctCurves);
		}

		public static bool IsDuctFitting(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_DuctFitting);
		}

		public static bool IsDuctAccessory(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_DuctAccessory);
		}

		public static bool IsDuctTerminal(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_DuctTerminal);
		}

		public static bool IsPipe(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_PipeCurves);
		}

		public static bool IsFlexPipe(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_FlexPipeCurves);
		}

		public static bool IsPipeFitting(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_PipeFitting);
		}

		public static bool IsPipeAccessory(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_PipeAccessory);
		}

		public static bool IsMechanicalEquipment(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_MechanicalEquipment);
		}

		public static bool IsPlumbingFixtures(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_PlumbingFixtures) || DbUtils.IsWashingMachine(element);
		}

		private static bool IsWashingMachine(Element element)
		{
			FamilyInstance familyInstance = element as FamilyInstance;
			return familyInstance != null && (familyInstance.Symbol.Family.Name.Contains("洗衣机") || familyInstance.Symbol.Name.Contains("洗衣机")) && DbUtils.TestCategory(element, BuiltInCategory.OST_SpecialityEquipment);
		}

		public static bool IsFireEquipment(Element element)
		{
			bool flag = false;
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance != null && (familyInstance.Symbol.Family.Name.Contains("消火栓") || familyInstance.Symbol.Family.Name.Contains("消防")))
			{
				flag = true;
			}
			return DbUtils.TestCategory(element, BuiltInCategory.OST_MechanicalEquipment) && flag;
		}

		public static bool IsSprinkler(Element element)
		{
			return DbUtils.TestCategory(element, BuiltInCategory.OST_Sprinklers);
		}

		public static bool HasParameter(Element elem, BuiltInParameter parameterId)
		{
			Parameter parameter = elem.GetParameter(parameterId);
			return parameter != null;
		}

		public static bool HasParameter(Element elem, string paramName)
		{
			Parameter parameter = elem.GetParameter(paramName);
			return parameter != null;
		}

		public static string GetElementParameterValue(Element elem, BuiltInParameter parameterId)
		{
			Parameter parameter = elem.GetParameter(parameterId);
			if (parameter == null)
			{
				return "";
			}
			return parameter.AsString();
		}

		private static double Tol = 0.04;
	}
}
